//
// Created by djy on 2019/7/23.
//
#include <string.h>
#include <stdio.h>
#include "setting.h"
#include "virtual_flash.h"
#include "comfun.h"
#include "auto_report.h"


setting_t setting;
static uint32_t setting_start_addr = SETTING_INVALID_ADDR;

static void board_feed_wdg()
{

}

void dev_show(void)
{
    static char str[34];

    printf("AID: %s\n", arr2str(setting.encode.id, sizeof(setting.encode.id), str, sizeof(str)));
    printf("PWD: %s\n", arr2str(setting.encode.pwd, sizeof(setting.encode.pwd), str, sizeof(str)));
    printf("SN: %s\n",  arr2str(setting.encode.sn, sizeof(setting.encode.sn), str, sizeof(str)));
    printf("DKey: %s\n", arr2str(setting.encode.dkey, sizeof(setting.encode.dkey), str, sizeof(str)));
    printf("PID: %s\n", arr2str(setting.para.panid, sizeof(setting.para.panid), str, sizeof(str)));
    printf("GID: %s\n", arr2str(setting.para.gid, sizeof(setting.para.gid), str, sizeof(str)));
    printf("SID: %s\n", arr2str(setting.para.sid, sizeof(setting.para.sid), str, sizeof(str)));
    //printf("TEST:%s\n", arr2str(setting.test, sizeof(setting.test),str, sizeof(str)));

    for(int i=0;i<=7;i++)
    {
        printf("SENSOR_AID[%d]: %d\n",i,get_le_val(setting.dev_infor.sensor_archives[i],4));
    }
    printf("DELAYTIME: %d S\n", get_le_val(setting.dev_infor.power_on_delay_time,2));
    printf("LUX STEP: %d\n", get_le_val(setting.dev_infor.lux_report_step,2));
    printf("LUX FREQ: %d\n", get_le_val(setting.dev_infor.lux_report_freq,2));
    printf("TEMP STEP: %d\n", get_le_val(setting.dev_infor.temp_report_step,2));
    printf("TEMP FREQ: %d\n", get_le_val(setting.dev_infor.temp_report_freq,2));
    printf("HUMI STEP: %d\n", get_le_val(setting.dev_infor.humi_report_step,2));
    printf("HUMI FREQ: %d\n", get_le_val(setting.dev_infor.humi_report_freq,2));
    printf("-------------------------------------------\n\n");
}


static void sensor_archives_default(void)
{
    put_le_val(1, setting.dev_infor.sensor_archives[0], 4);
    put_le_val(2, setting.dev_infor.sensor_archives[1], 4);
    put_le_val(3, setting.dev_infor.sensor_archives[2], 4);
    put_le_val(4, setting.dev_infor.sensor_archives[3], 4);

    put_le_val(5, setting.dev_infor.sensor_archives[4], 4);
    put_le_val(6, setting.dev_infor.sensor_archives[5], 4);
    put_le_val(7, setting.dev_infor.sensor_archives[6], 4);
    put_le_val(8, setting.dev_infor.sensor_archives[7], 4);

    setting.dev_infor.sensor_chn_nums = 8;//default  8 chns
}

static void setting_default(void)
{
    memset(&setting, 0, sizeof(setting));
    uint8_t sn[]= {0x31,0x71,0x41,0x70,0x00,0x11,0x93,0x51,0x99,0x00,0x00,0x04};
    uint8_t dk[]= {0x30,0x30,0x30,0x30,0x30,0x5A,0x34,0x48};
    put_le_val(247782, setting.encode.id, 4);
    put_le_val(5819, setting.encode.pwd, 2);
    put_le_val(600, setting.para.sid, 2);

    uint8_t gid[] ={0x01,0x00,0x00,0x00};
    memcpy(setting.para.gid,gid,4);
    memcpy(setting.encode.sn, sn, sizeof(sn));
    memcpy(setting.encode.dkey, dk, sizeof(dk));

    setting.dev_infor.dev_mode  = MODE_REPORT_GW;
    setting.dev_infor.report    = REPORT_GW;

    setting.dev_infor.lux_report_freq[1] = 0;
    setting.dev_infor.lux_report_freq[0] = 60;
    setting.dev_infor.lux_report_step[1] = 0;
    setting.dev_infor.lux_report_step[0] = 0;

    setting.dev_infor.temp_report_freq[1] = 0;
    setting.dev_infor.temp_report_freq[0] = 60;
    setting.dev_infor.temp_report_step[1] = 0;
    setting.dev_infor.temp_report_step[0] = 0;

    setting.dev_infor.humi_report_freq[1] = 0;
    setting.dev_infor.humi_report_freq[0] = 60;
    setting.dev_infor.humi_report_step[1] = 0;
    setting.dev_infor.humi_report_step[0] = 0;

    setting.dev_infor.power_on_delay_time[0]  =60;
    setting.dev_infor.power_on_delay_time[1]  =0;

    sensor_archives_default();
}

void setting_save(void)
{
    setting_hdr_t hdr;
    uint32_t addr = setting_start_addr + sizeof(setting_t);//璧峰鍦板潃+褰撳墠浣跨敤鐨勬暟鎹暱搴�
    BOOL new_sec = FALSE;
    printf("setting save...\n");
    //濡傛灉addr澶т簬瀛樺偍绌洪棿
    if (addr >= SETTING_FROM + SETTING_SIZE || (addr + sizeof(setting_t) >= SETTING_FROM + SETTING_SIZE))
    {
        addr = SETTING_FROM; //瀛樺偍鍦板潃鍒囨崲鍒版渶寮�濮�
        new_sec = TRUE;      //鏇存柊閲嶆柊瀛樺偍鏍囧織
    }
    //濡傛灉鍗冲皢浣跨敤鐨勫瓨鍌ㄧ┖闂磋秴杩囦竴椤�
    if ((addr & FLASH_SECTOR_MASK) + sizeof(setting_t) > FLASH_SECTOR_SIZE)
    {
        addr = (addr + FLASH_SECTOR_SIZE) & (~FLASH_SECTOR_MASK);//浠庝笅涓�椤靛紑濮�
        new_sec = TRUE;
    }
    //棣栨浣跨敤
    if (!(addr & FLASH_SECTOR_MASK))
    {
        new_sec = TRUE;
    }

    /* erase next sector if need a new sector */
    if (new_sec)
    {
        flash_erase(addr,FLASH_SECTOR_SIZE);
    }

    /* check memory */
    setting_t tmp;
    flash_read((uint8_t *)&tmp, addr, sizeof(tmp));
    if(!is_all_xx((uint8_t *)&tmp, 0xFF, sizeof(tmp)))
    {
        printf("err occur\n");
        return ;
    }

    //save setting data
    if(!flash_write(setting_data_addr(setting),addr + sizeof(setting_hdr_t),SETTING_DAT_SIZE))
        printf("flash write err\n");

    hdr.crc = add_crc16(setting_data_addr(setting), SETTING_DAT_SIZE);
    hdr.magic = SETTING_MAGIC;
    flash_write((uint8_t *)&hdr,addr,sizeof(hdr));//save setting crc &magic

    if (setting_start_addr < SETTING_FROM + SETTING_SIZE)
    {
        memset(&hdr, 0, sizeof(hdr));
        flash_write((uint8_t *)&hdr,setting_start_addr,sizeof(hdr));//change last setting crc &magic
    }

    setting_start_addr = addr;
    printf("setting_start_addr is  0x%06X!\r\n", addr);
    printf("setting save done \n\n");
}

void setting_load(void)
{
    setting_hdr_t hdr;
    uint32_t addr = SETTING_FROM;

    printf("setting load...\n");
    //  鍙傛暟瀛樺偍璧峰鍦板潃            鏄惁瓒呭嚭鑼冨洿                       姝ラ暱锛氬弬鏁板瓨鍌ㄥぇ灏�
    for (addr = SETTING_FROM; addr < SETTING_FROM + SETTING_SIZE; addr += sizeof(setting_t))
    {
        //灏嗚璇诲彇鐨刦lash鍦板潃瓒呰繃涓�鏁撮〉
        if ((addr & FLASH_SECTOR_MASK) + sizeof(setting_t) > FLASH_SECTOR_SIZE)
        {
            addr = (addr + FLASH_SECTOR_SIZE) & (~FLASH_SECTOR_MASK); //浠庝笅涓�椤靛紑濮�
        }

        if(addr >= SETTING_FROM + SETTING_SIZE)//涓嬩竴椤佃秴鍑哄鍧�鑼冨洿
        {
            break;
        }
        board_feed_wdg();//璇诲彇flash鏃堕棿闀� 闃叉鐪嬮棬鐙楀浣�

        //璇诲彇hdr  鏍￠獙 magic
        flash_read((uint8_t*)&hdr,addr, SETTING_HDR_SIZE);
        if (hdr.magic != SETTING_MAGIC) continue;//濡傛灉瀛樺偍鏍囧織涓嶄竴鏍�  缁х画寰幆

        //璇诲彇鍓╀綑鏁版嵁  鏍￠獙CRC
        flash_read(setting_data_addr(setting),addr + SETTING_HDR_SIZE,SETTING_DAT_SIZE);
        if (hdr.crc != add_crc16(setting_data_addr(setting), SETTING_DAT_SIZE)) continue;//crc鏍￠獙涓嶈繃  缁х画寰幆

        //鎵惧埌姝ｇ‘鏁版嵁
        setting_start_addr = addr;
        printf("setting_load here has data addr: 0x%06X!\r\n", addr);
        return;
    }

    setting_default();//鏈壘鍒版纭暟鎹�  榛樿閮ㄥ垎鍙傛暟
    setting_save();//鍙傛暟淇濆瓨
}
